package com.bsoft.gol.hcs.utils;

import com.bsoft.gol.hcs.base.BaseHisPlateformXmlResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ctd.util.xml.jaxb.JAXBUtils;
import hcn.util.BaseResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.dom4j.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.atag.util.http.KdHttpClientUtil;

import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xhf
 * @date 2019/11/14 18:46
 * @Description
 */
public class CheckAppointmentUtil {
    private final static Logger logger = LoggerFactory.getLogger(CheckAppointmentUtil.class);
    // webservice的wsdl地址
//    private static final String WSDLURL = "http://10.10.2.85:8089/mrc/ws/service.ws?wsdl";
    private static final String WSDLURL = "http://10.8.3.125:8089/mrc/ws/service.ws?wsdl";


    public static JSONObject getJsonDataFromHis(String webServiceUrl, String serviceName, String msgHeaderXml, String queryConditionsXml) throws XMLStreamException, IOException {
        logger.info("service---------------------:{}", serviceName);
        logger.info("{}入参:{}", serviceName, queryConditionsXml);
        Date begin = new Date();
        JSONObject jsonObjectBSXml = null;
        // 设置编码。(因为是直接传的xml,所以我们设置为text/xml;charset=utf8)
        final String contentType = "text/xml;charset=utf8";
        /// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
        String message = "<![CDATA[\n" +
                "<BSXml>\n" +
                msgHeaderXml +
                queryConditionsXml +
                "</BSXml>\n" +
                "]]>";
        StringBuffer xMLcontent = new StringBuffer("");
        xMLcontent.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:com=\"http://com.bsoft.ws\">\n");
        xMLcontent.append("   <soapenv:Header/>\n");
        xMLcontent.append("   <soapenv:Body>\n");
        xMLcontent.append("      <com:" + serviceName + ">\n");
        xMLcontent.append("         <!--Optional:-->\n");
        xMLcontent.append("         <com:message>" + message + "</com:message>\n");
        xMLcontent.append("      </com:" + serviceName + ">\n");
        xMLcontent.append("   </soapenv:Body>\n");
        xMLcontent.append("</soapenv:Envelope>");
        String request = xMLcontent.toString();
        logger.info("{}完整入参:{}", serviceName, request);
        // 调用工具类方法发送http请求
        String responseXML = KdHttpClientUtil.doXmlPost(webServiceUrl, contentType, request);
        try {
            Document document = DocumentHelper.parseText(responseXML);
            JSONObject jSONObjectData = elementToJSONObject(document.getRootElement());
            String serviceNameResponse = jSONObjectData.getJSONArray("Body").getJSONObject(0).get(serviceName + "Response").toString();
            String serviceNameXml = JSONArray.parseArray(serviceNameResponse).getJSONObject(0).get(serviceName).toString();
            JSONObject dataJson = documentToJSONObject(serviceNameXml);
            jsonObjectBSXml = dataJson.getJSONArray("BSXml").getJSONObject(0);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        logger.info("{}返回值json:{}", serviceName, jsonObjectBSXml.toJSONString());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serviceName + ")耗费时间：" + (System.currentTimeMillis() - begin.getTime()) + "毫秒——————————");
        return jsonObjectBSXml;
    }

    public static String getJsonDataFromPlatform(String postServiceUrl, String serviceName, String request) throws XMLStreamException, IOException {
        logger.info("service---------------------:{}", serviceName);
        logger.info("{}入参:{}", serviceName, request);
        Date begin = new Date();
        // 设置编码。(因为是直接传的xml,所以我们设置为application/xml;charset=utf8)
        final String contentType = "application/xml;charset=utf8";
        logger.info("{}完整入参:{}", serviceName, request);
        // 调用工具类方法发送http请求
        String responseXML = KdHttpClientUtil.doXmlPost(postServiceUrl, contentType, request);
        //String jsonStr = XmlToJson.xml2jsonString(responseXML);
        logger.info("{}返回值json:{}", serviceName, responseXML);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serviceName + ")耗费时间：" + (System.currentTimeMillis() - begin.getTime()) + "毫秒——————————");
        return responseXML;
    }

    public static String getJsonDataFromPlatform(String postServiceUrl, String serviceName, String msgHeaderXml, String queryConditionsXml) throws XMLStreamException, IOException {
        logger.info("service---------------------:{}", serviceName);
        logger.info("{}入参:{}", serviceName, queryConditionsXml);
        Date begin = new Date();
        // 设置编码。(因为是直接传的xml,所以我们设置为application/xml;charset=utf8)
        final String contentType = "application/xml;charset=utf8";
        /// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
        StringBuffer xMLcontent = new StringBuffer("");
        xMLcontent.append("<BSXml>");
        xMLcontent.append(msgHeaderXml);
        xMLcontent.append(queryConditionsXml);
        xMLcontent.append("</BSXml>");
        String request = xMLcontent.toString();
        logger.info("{}完整入参:{}", serviceName, request);
        // 调用工具类方法发送http请求
        String responseXML = KdHttpClientUtil.doXmlPost(postServiceUrl, contentType, request);
        //String jsonStr = XmlToJson.xml2jsonString(responseXML);
        logger.info("{}返回值json:{}", serviceName, responseXML);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serviceName + ")耗费时间：" + (System.currentTimeMillis() - begin.getTime()) + "毫秒——————————");
        return responseXML;
    }

    public static String getSaveJsonDataFromPlatform(String postServiceUrl, String serviceName, String xml) throws XMLStreamException, IOException {
        logger.info("service---------------------:{}", serviceName);
        logger.info("{}入参:{}", serviceName, xml);
        Date begin = new Date();
        // 设置编码。(因为是直接传的xml,所以我们设置为application/xml;charset=utf8)
        final String contentType = "application/xml;charset=utf8";
        StringBuffer xMLcontent = new StringBuffer("");
        xMLcontent.append(xml);
        String request = xMLcontent.toString();
        logger.info("{}完整入参:{}", serviceName, request);
        // 调用工具类方法发送http请求
        String responseXML = KdHttpClientUtil.doXmlPost(postServiceUrl, contentType, request);
        logger.info("{}返回值json:{}", serviceName, responseXML);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serviceName + ")耗费时间：" + (System.currentTimeMillis() - begin.getTime()) + "毫秒——————————");
        return responseXML;
    }

    public static BaseResponse postFromPlatform(String postServiceUrl, String serviceName, String msgHeaderXml, String queryConditionsXml) throws XMLStreamException, IOException {
        logger.info("service---------------------:{}", serviceName);
        logger.info("{}入参:{}", serviceName, queryConditionsXml);
        Date begin = new Date();
        // 设置编码。(因为是直接传的xml,所以我们设置为application/xml;charset=utf8)
        final String contentType = "application/xml;charset=utf8";
        /// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
        StringBuffer xMLcontent = new StringBuffer("");
        xMLcontent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        xMLcontent.append("<BSXml>");
        xMLcontent.append(msgHeaderXml);
        xMLcontent.append("");
        xMLcontent.append(queryConditionsXml);
        xMLcontent.append("</BSXml>");
        String request = xMLcontent.toString();
        logger.info("{}完整入参:{}", serviceName, request);

        Map<String,String> map = new HashMap<>();
        map.put("service",serviceName);
        map.put("parameter",request);
        // 调用工具类方法发送http请求
        BaseResponse baseResponse = new BaseResponse();
        baseResponse = KdHttpClientUtil.postMap(postServiceUrl,null,map);
        logger.info("{}返回值xml:{}", serviceName, baseResponse.getData());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serviceName + ")耗费时间：" + (System.currentTimeMillis() - begin.getTime()) + "毫秒——————————");
        return baseResponse;
    }





    public static String mapToXml(Map<String, String> paramsMap, String root) {
        StringBuilder sb = new StringBuilder();
        if (CommonUtils.isNotEmpty(root)) {
            sb.append("<" + root + ">");
        }
        for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
            String value = entry.getValue();
            if (value != null && !"".equals(value)) {
                sb.append("<").append(entry.getKey()).append(">").append(value).append("</").append(entry.getKey())
                        .append(">");
            }
        }
        if (CommonUtils.isNotEmpty(root)) {
            sb.append("</" + root + ">");
        }
        return sb.toString();
    }


    /**
     * org.dom4j.Element 转  com.alibaba.fastjson.JSONObject
     *
     * @param node
     * @return
     */
    public static JSONObject elementToJSONObject(Element node) {
        JSONObject result = new JSONObject();
        // 当前节点的名称、文本内容和属性
        List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
        for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
            result.put(attr.getName(), attr.getValue());
        }
        // 递归遍历当前节点所有的子节点
        List<Element> listElement = node.elements();// 所有一级子节点的list
        if (!listElement.isEmpty()) {
            for (Element e : listElement) {// 遍历所有一级子节点
                if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点
                {
                    result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待
                } else {
                    if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性
                    {
                        result.put(e.getName(), new JSONArray());// 没有则创建
                    }
                    ((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中
                }
            }
        }
        return result;
    }

    public static Document strToDocument(String xml) {
        try {
            //加上xml标签是为了获取最外层的标签，如果不需要可以去掉
            return DocumentHelper.parseText("<xml>" + xml + "</xml>");
        } catch (DocumentException e) {
            return null;
        }
    }

    public static JSONObject documentToJSONObject(String xml) {
        return elementToJSONObject(strToDocument(xml).getRootElement());
    }

    /**
     * @description: 根据xml获取BaseHisPlateformXmlResponse
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/11/3 12:25
     * @param: xmlStr
     * @return: hcn.protocol.base.hisPlateform.BaseHisPlateformXmlResponse
     */
    public static BaseHisPlateformXmlResponse getBaseHisPlateformXmlResponse(String xmlStr){
        BaseHisPlateformXmlResponse bodyResponse = JAXBUtils.xml2Object(xmlStr, BaseHisPlateformXmlResponse.class);
        return bodyResponse;
    }

    public static String getSoapXmlWithOutBSXml(String service, String xml) {
        return "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.access.hai/\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n" +
                "      <ws:invoke>\n" +
                "         <service>" + service + "</service>\n" +
                "         <urid></urid>\n" +
                "         <pwd></pwd>\n" +
                "         <parameter><![CDATA[<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xml + "]]></parameter>\n" +
                "      </ws:invoke>\n" +
                "   </soapenv:Body>\n" +
                "</soapenv:Envelope>";
    }

    public static String getSexInfo(String sex) {
        if ("1".equals(sex)) {
            return "男";
        } else {
            return "女";
        }
    }

    /**
     * @description: xml请求，返回BSXml节点的数据
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/11/3 17:41
     */
    public static String getStringDataFromPhis(String webServiceUrl, String queryConditionsXml) throws IOException {
        logger.info("{}入参:{}", webServiceUrl, queryConditionsXml);
        String aReturn = "";
        // 调用工具类方法发送http请求
        String responseXML = doHttpPostByHttpClient(webServiceUrl, "text/xml", queryConditionsXml);
        try {
            Document document = DocumentHelper.parseText(responseXML);
            Element rootElement = document.getRootElement();
            List<Element> listElement = rootElement.elements();
            for (Element element : listElement) {
                aReturn = element.getStringValue();
                break;
            }
            ;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        logger.info("BSXml节点的数据出参aReturn:{}", aReturn);
        return aReturn;
    }

    /**
     * 使用apache的HttpClient发送http
     *
     * @param wsdlURL     请求URL
     * @param contentType 如:application/json;charset=utf8
     * @param content     数据内容
     * @DATE 2018年9月22日 下午10:29:17
     */
    public static String doHttpPostByHttpClient(String wsdlURL, String contentType, String content)
            throws ClientProtocolException, IOException {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient HttpClientUtils = HttpClientBuilder.create().build();
        // 创建Post请求
        HttpPost httpPost = new HttpPost(wsdlURL);
        StringEntity entity = new StringEntity(content.toString(), "UTF-8");
        // 将数据放入entity中
        httpPost.setEntity(entity);
        httpPost.setHeader("Content-Type", contentType);
        // 响应模型
        CloseableHttpResponse response = null;
        String result = null;
        try {
            // 由客户端执行(发送)Post请求
            response = HttpClientUtils.execute(httpPost);
            // 从响应模型中获取响应实体
            // 注意:和doHttpPostByRestTemplate方法用的不是同一个HttpEntity
            org.apache.http.HttpEntity responseEntity = response.getEntity();
            System.out.println("响应ContentType为:" + responseEntity.getContentType());
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity);
                System.out.println("响应内容为:" + result);
            }
        } finally {
            // 释放资源
            if (HttpClientUtils != null) {
                HttpClientUtils.close();
            }
            if (response != null) {
                response.close();
            }
        }
        return result;
    }
    public static void main(String[] args) {
        String responseXML = "<?xml version=\"1.0\" ?><S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\"><S:Body><ns2:invokeResponse xmlns:ns2=\"http://ws.access.hai/\"><return>&lt;BSXml&gt;\n" +
                "&lt;MsgHeader&gt;\n" +
                "   &lt;Organization&gt;&lt;/Organization&gt;\n" +
                "   &lt;Sender&gt;&lt;/Sender&gt;\n" +
                "   &lt;MsgType&gt;&lt;/MsgType&gt;\n" +
                "   &lt;MsgVersion&gt;&lt;/MsgVersion&gt;\n" +
                "&lt;/MsgHeader&gt;\n" +
                "&lt;MsgBody&gt;\n" +
                "   &lt;Status&gt;false&lt;/Status&gt;   \n" +
                "   &lt;Code&gt;201&lt;/Code&gt;\n" +
                "   &lt;Detail&gt;http://webpacs.bsoft.com.cn:5290/main/screenage.aspx、、?studyid=FS201027001&studyuid=&accnumber=&studydate=&lt;/Detail&gt;\n" +
                "&lt;/MsgBody&gt;\n" +
                "&lt;/BSXml&gt;\n" +
                "</return></ns2:invokeResponse></S:Body></S:Envelope>";

        try {
            Document document = DocumentHelper.parseText(responseXML);
            Element rootElement = document.getRootElement();
            List<Element> listElement = rootElement.elements();
            for (Element element : listElement) {
                System.out.println(element.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

}

